package com.letv.download;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.letv.bean.SummaryBean;
import com.letv.common.ConnectionManager;
import com.letv.common.Constants;
import com.letv.common.ProcessData;
import com.letv.conf.ConfigFactory;
import com.letv.mms.cache.factory.CacheFactory;
import com.letv.util.DateUtil;
import com.letv.util.SQLUtil;

/**
 * @author GaoJiaWei
 *
 */
public class DownloadWorker extends DownloadMapperService implements Callable<DownloadResult> {

    Logger log = LoggerFactory.getLogger(DownloadWorker.class.getCanonicalName());
    private String mapFlag="1";
    private String mapKeyPrefix;

    public DownloadWorker(String tbName, String destTbName, String type, Long begin, Long end) {
        log.debug("current thread id=" + Thread.currentThread().getId() + " name:" + Thread.currentThread().getName()
                + " begin=" + begin + " end=" + end);
        this.tableName = tbName;
        this.type = type;
        this.begin = begin;
        this.end = end;
        this.mapFlag =  ConfigFactory.getString("star.mapLeid");
        this.mapKeyPrefix = ConfigFactory.getString("star.keyprefix");
        if (mapKeyPrefix==null) {
            mapKeyPrefix = "leid_";
        }
    }

    public DownloadResult call() throws Exception {
        return searchAndIntoDB(this.type);
    }

    private DownloadResult searchAndIntoDB(String type) {
        DownloadResult result = new DownloadResult();
        ArrayList<Map<String, Object>> lists = new ArrayList<Map<String, Object>>();
        ConnectionManager cm = null;
        try {
            cm = ConnectionManager.getInstance();
        } catch (Exception e) {
            log.error("connection get instance error!", e);
            result.setRecordsCnt(0);
            result.setFlag(false);
            return result;
        }
        Connection mmsConn = null;
        Connection lesoConn = null;
        try {
            if (Constants.INDEX_VIDEO.equals(type) || Constants.INDEX_ALBUM.equals(type)
                    || Constants.INDEX_STAR.equals(type)) {
                mmsConn = cm.getConnectionFromMMS();
                lists = SQLUtil.getSourceData(mmsConn, type, this.getBegin(), this.getEnd());
            } else if (Constants.INDEX_LESO.equals(type)) {
                lesoConn = cm.getConnectionFromLeso();
                lists = SQLUtil.getLesoAlbumSourceData(lesoConn, "leso.SQL2", this.getBegin(), this.getEnd());
                List<Map<String, Object>> allOtherSourceDetailList = new ArrayList<Map<String, Object>>();
                for (Map<String, Object> map : lists) {
                    try {
                        Map<String, Object> tmp = SQLUtil.getSourceDataById(lesoConn, type,
                                Long.valueOf(map.get("aid").toString()));
                        if (tmp == null) {
                            log.info("video table non't have data,album_id=" + map.get("aid").toString());
                        } else {
                            log.info("aid={},letv_album_id={}",map.get("aid"),tmp.get("vrsAid"));
                            if (tmp.get("vid") != null && (!"".equals(tmp.get("vid").toString()))) {
                                map.putAll(tmp);
                                super.mapperVideoList(lesoConn, map);
                                List<Map<String, Object>> otherSourceDetailList = super.getOtherSourceDetailList(lesoConn, map);
                                if(null != otherSourceDetailList) {
                                    allOtherSourceDetailList.addAll(otherSourceDetailList);
                                }
                                if(super.isContinue()){
                                    continue;
                                }
                            }
                        }
                    } catch(Exception et) {
                        log.error("fail to get album,id=" + map.get("aid").toString(), et);
                    }
                }
                lists.addAll(allOtherSourceDetailList);
                log.info("the number of total Records is:" + lists.size() + ",begin/end=" + begin + "/" + end);
            }
        } catch (Exception e) {
            log.error("get " + type + " data from source table error!", e);
        } finally {
            if (Constants.INDEX_VIDEO.equals(type) || Constants.INDEX_ALBUM.equals(type)
                    || Constants.INDEX_STAR.equals(type)) {
                SQLUtil.close(mmsConn);
                log.info("mmsConn close!");
            } else if (Constants.INDEX_LESO.equals(type)) {
                SQLUtil.close(lesoConn);
                log.info("lesoConn close!");
            }
        }
        ArrayList<String> records = new ArrayList<String>();
        log.info("begin mapping " + type + " data!");
        records = processData(lists, this.type);
        log.info("begin insert " + type + " data!");
        Connection localConn = cm.getConnection();
        try {
            if (records.size() > 0) {
                SQLUtil.insertSourceData(localConn, this.type, records);
                log.info("insert " + type + " data, size=" + records.size());
                result.setRecordsCnt(records.size());
                result.setFlag(true);
            } else {
                log.info("this time get 0 " + type + " records, not data insert! flag=" + result.isFlag());
            }
        } catch (Exception e) {
            result.setRecordsCnt(0);
            result.setFlag(false);
            log.error("insert " + type + " data ERROR", e);
        } finally {
            SQLUtil.close(localConn);
        }
        return result;
    }

    private ArrayList<String> processData(ArrayList<Map<String, Object>> lists, String type) {
        ArrayList<String> records = new ArrayList<String>();
        if (Constants.INDEX_VIDEO.equals(type)) {
            for (int i = 0; i < lists.size(); i++) {
                Map<String, Object> m = lists.get(i);
                try {
                    String record = ProcessData.getVideoStr(m);
                    records.add(record);
                } catch (Exception e) {
                    log.error("process source data id=" + m.get("ID") + " type=" + type + " error!", e);
                    continue;
                }
            }
        } else if (Constants.INDEX_LESO.equals(type)) {
            for (int i = 0; i < lists.size(); i++) {
                Map<String, Object> m = lists.get(i);
                //if (m.get("vid") != null) {
                    try {
                        String record = ProcessData.getLesoStr(m);
                        records.add(record);
                    } catch (Exception e) {
                        log.error("process source data id=" + m.get("ID") + " type=" + type + " error!", e);
                        continue;
                    }
                //}
            }
        } else if (Constants.INDEX_STAR.equals(type)) {
            for (int i = 0; i < lists.size(); i++) {
                Map<String, Object> m = lists.get(i);
                try {
                    String record = ProcessData.getStarStr_new(m);
                    log.debug(record);
                    records.add(record);
                    starIdMapLeid(m);
                } catch (Exception e) {
                    log.error("process source data id=" + m.get("ID") + " type=" + type + " error!", e);
                    continue;
                }
            }
        } else if (Constants.INDEX_ALBUM.equals(type)) {
            for (int i = 0; i < lists.size(); i++) {
                Map<String, Object> m = lists.get(i);
                try {
                    String record = ProcessData.getAlbumStr(m);
                    records.add(record);
                } catch (Exception e) {
                    log.error("process source data id=" + m.get("ID") + ", type=" + type + " error!", e);
                    continue;
                }
            }
        }

        return records;
    }

    private void starIdMapLeid(Map<String, Object> m) {
        if ("1".equals(this.mapFlag)){
            Object leid = m.get("le_id");
            if ( leid != null) {
                String  key = mapKeyPrefix+leid.toString();
                CacheFactory.getCache().set(key, m.get("id").toString(), DateUtil.getIndexDayRefCurr(Calendar.HOUR, 48));
            }
        }
    }

    public Long getBegin() {
        return begin;
    }

    public void setBegin(Long begin) {
        this.begin = begin;
    }

    public Long getEnd() {
        return end;
    }

    public void setEnd(Long end) {
        this.end = end;
    }

    public String getTableName() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    private Long begin;
    private Long end;
    private String tableName;
    private String type;

	@Override
	public SummaryBean down(String type) {
		return null;
	}

	@Override
	public SummaryBean downLesoExtraet(String type) {
		return null;
	}

	@Override
	public boolean downDataById(String type, int id) {
		return false;
	}

	@Override
	public boolean delDataById(String type, int id) {
		return false;
	}

	@Override
	public boolean updDataById(String type, int id) {
		return false;
	}
}